﻿//--------------------------------------------------------------------------
// <copyright file="AppDefiner.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
// <summary>AppDefiner</summary>
//--------------------------------------------------------------------------
using System;
[assembly: CLSCompliant(true)]
namespace MS.Msn.MediaSolutions.Common
{
    using System.Collections.Generic;
    using System.Text;
    using System.Globalization;
    using System.Configuration;
    using System.Xml;
    using System.IO;
    using System.Xml.Serialization;

    /// <summary>
    /// AppDefiner
    /// </summary>
    public static class Apps
    {
        private const string ARG_NULL_EX_FORMAT = "parameter:{0} CANNOT be null";
        private const string CONFIG_SECTION_NAME = "AppConfiguration";


        private static readonly CultureInfo defaultCulture = new CultureInfo("en-us");

        /// <summary>
        /// default culture
        /// </summary>
        public static CultureInfo DefaultCulture
        {
            get { return Apps.defaultCulture; }
        }

        /// <summary>
        /// NowMs Short String
        /// </summary>
        public static string NowMsShortString
        {
            get { return DateTime.Now.ToString("yyyyMMddHHmmss", DefaultCulture) + DateTime.Now.Millisecond.ToString(DefaultCulture).PadLeft(3, '0'); }
        }

        /// <summary>
        /// NowMs Whole String
        /// </summary>
        public static string NowMsWholeString
        {
            get { return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss'", DefaultCulture) + DateTime.Now.Millisecond.ToString(DefaultCulture).PadLeft(3, '0'); }
        }

        /// <summary>
        /// GetArgNullExString
        /// </summary>
        /// <param name="parName"></param>
        /// <returns></returns>
        public static string GetArgNullExString(string parName)
        {
            return string.Format(defaultCulture, ARG_NULL_EX_FORMAT, parName);
        }

        #region get configuration

        /// <summary>
        /// get configuration instance from a config section
        /// </summary>
        /// <param name="sectionName">section tag name</param>
        /// <param name="inst">config instance</param>
        /// <returns>configuration instance</returns>
        public static T GetInstance<T>(string sectionName, T inst)
        {
            if (object.Equals(inst, null) || object.Equals(inst, default(T)))
            {
                inst = (T)ConfigurationManager.GetSection(sectionName);
            }
            return inst;
        }

        /// <summary>
        /// et configuration instance from a config XML file
        /// </summary>
        /// <param name="filePath">file path</param>
        /// <param name="xPath">config section Xpath</param>
        /// <param name="inst">config instance</param>
        /// <returns>configuration instance</returns>
        public static T GetInstance<T>(string filePath, string xPath, T inst)
        {
            if (object.Equals(inst, null) || object.Equals(inst, default(T)))
            {
                if (File.Exists(filePath))
                {
                    XmlDocument xdoc = new XmlDocument();
                    if (string.IsNullOrEmpty(xPath.Trim()))
                    {
                        xPath = "/";
                    }
                    xdoc.Load(filePath);
                    XmlNode xnod = xdoc.SelectSingleNode(xPath);
                    inst = (T)Xmls.EntityFromXml(xnod.OuterXml, typeof(T));
                }
            }
            return inst;
        }

        /// <summary>
        /// GetInstance
        /// </summary>
        /// <typeparam name="T">instance</typeparam>
        /// <param name="inst">inst</param>
        public static T GetInstance<T>(T inst)
        {
            if (object.Equals(inst, null) || object.Equals(inst, default(T)))
            {
                inst = GetInstance<T>(AppDomain.CurrentDomain.BaseDirectory + CONFIG_SECTION_NAME + ".config", "/", inst);
                inst = GetInstance<T>(CONFIG_SECTION_NAME, inst);
            }
            return inst;
        }

        #endregion

        #region save configuration

        /// <summary>
        /// save configuration
        /// </summary>
        /// <param name="filePath">configuration instance</param>
        /// <param name="inst">config instance</param>
        /// <returns>success/failed</returns>
        public static bool SaveToFile<T>(string filePath, T inst)
        {
            return SaveToFile(inst, filePath);
        }

        /// <summary>
        /// save configuration
        /// </summary>
        /// <param name="inst">configuration instance</param>
        /// <param name="filePath">file path</param>
        /// <returns>success/failed</returns>
        public static bool SaveToFile<T>(T inst, string filePath)
        {
            using (StreamWriter sw = new StreamWriter(filePath, false, Encoding.UTF8))
            {
                sw.Write(Xmls.EntityToXml(inst));
                sw.Close();
            }
            return true;
        }

        #endregion

    }

    /// <summary>
    /// CustomConfigurationSection
    /// </summary>
    public abstract class CustomConfigBase : IConfigurationSectionHandler
    {
        #region IConfigurationSectionHandler Members

        /// <summary>
        /// create custom config
        /// </summary>
        /// <param name="parent">parent node tag name</param>
        /// <param name="configContext">congig context</param>
        /// <param name="section">section tag name</param>
        /// <returns>config instance</returns>
        public object Create(object parent, object configContext, XmlNode section)
        {
            XmlSerializer ser = Xmls.GetXmlSerializer(this.GetType());
            return ser.Deserialize(new XmlNodeReader(section));
        }

        #endregion
    }
}
